package com.jyh.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

/**
 * 手动从Spring WebApplicationContext 容器中获得bean 依赖jar<br>
 * fastjson-1.1.41.jar<br>
 * spring-beans-4.0.0.RELEASE.jar<br>
 * spring-context-4.0.0.RELEASE.jar<br>
 * spring-core-4.0.0.RELEASE.jar<br>
 * 配置<br>
 * < bean id="beanUtils" class="com.xsh.utils.bean.BeanUtils" / >
 */
@Component
public class BeanUtils implements ApplicationContextAware {

	// 存储spring应用程序对象
	private static ApplicationContext applicationContext;

	/**
	 * 根据beanId获取一个bean
	 * 
	 * @param beanId
	 * @return
	 */
	public static Object getBean(String beanId) {
		return applicationContext.getBean(beanId);
	}

	/**
	 * 根据class获取一个bean
	 * 
	 * @param beanName
	 * @return
	 */
	public static <T> T getBean(Class<T> clazs) {
		return applicationContext.getBean(clazs);
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) {
		BeanUtils.applicationContext = applicationContext;
		System.out.println("=============已经获取到ApplicationContext==================");
	}

	public static Object invoke(String className, String methodName) {
		try {
			Class<?> cls = Class.forName(className);
			Object object = cls.newInstance();
			Field[] fields = object.getClass().getDeclaredFields();
			for (int i = 0; i < fields.length; i++) {
				fields[i].setAccessible(true);
				Annotation[] anns = fields[i].getAnnotations();
				if (isConAutowired(anns)) {
					fields[i].set(object, applicationContext.getBean(fields[i].getType()));
				}
			}
			Method m = cls.getDeclaredMethod(methodName);
			Object obj = m.invoke(object);
			return obj;
		} catch (NoSuchMethodException | SecurityException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		}
	}

	private static boolean isConAutowired(Annotation... annotations) {
		if (annotations == null || annotations.length <= 0) {
			return false;
		}
		for (Annotation ann : annotations) {
			if (ann.annotationType().getName().equals("org.springframework.beans.factory.annotation.Autowired")) {
				return true;
			}
		}
		return false;
	}

	public static Object invokeSpring(String className, String methodName) {
		Object object = BeanUtils.getBean(className);
		if (object == null) {
			return null;
		}
		try {
			return ReflectUtils.invokeMethod(object, methodName);
		} catch (NoSuchMethodException | SecurityException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		}
	}

	public static Object invokeSpring(String className, String methodName, JSONObject params)
			throws InvocationTargetException {
		Object object = BeanUtils.getBean(className);
		if (object == null) {
			return null;
		}
		try {
			return ReflectUtils.invokeMethod(object, methodName, params);
		} catch (NoSuchMethodException | SecurityException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			throw new RuntimeException("运行时异常");
		}
	}

	public static Object invokeSpring(String className, String methodName, String params)
			throws InvocationTargetException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException {
		Object object = BeanUtils.getBean(className);
		if (object == null) {
			return null;
		}
		return ReflectUtils.invokeMethod(object, methodName, params);
	}
	
	public static Object invokeSpring(Class<?> cls, String methodName, String params)
			throws InvocationTargetException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException {
		Object object = BeanUtils.getBean(cls);
		if (object == null) {
			return null;
		}
		return ReflectUtils.invokeMethod(object, methodName, params);
	}
}
